﻿#region Copyright and Licensing Notice
// Copyright (C) 2011 Steven Bosnick
// 
// This program is open source software; you can redistribute it 
// and/or modifiy it under the terms of the Eclipse Public License,
// version 1.0.
// 
// This program is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A 
// PARTICULAR PURPOSE. See the Eclipse Public License for more
// details.
// 
// You should have received a copy of the Eclipse Public License 
// along with this program; if not, you can find a copy at
// "http://www.opensource.org/licenses/eclipse-1.0.php".
#endregion
using System;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;
using System.Threading;
using Autofac;
using BitwiseOre.SharedMemory.Context;
using BitwiseOre.SharedMemory.External;

namespace BitwiseOre.SharedMemory.Autofac
{
    internal sealed class ExternalsModule : Module
    {
        private const MemoryMappedFileAccess MemoryAccess = MemoryMappedFileAccess.ReadWrite;
        
        protected override void Load(ContainerBuilder builder)
        {
            builder.Register(
                c =>
                    {
                        var config = c.ResolveConfig<IMemoryMappedFileConfig>();
                        var sharedconfig = c.ResolveConfig<ISharedObjectConfig>();
                        return sharedconfig.Status == SharedObjectStatus.CreateNew
                                   ? MemoryMappedFile.CreateNew(config.Name, config.Capacity, MemoryAccess)
                                   : MemoryMappedFile.OpenExisting(config.Name);
                    })
                .InstancePerLifetimeScope();
            builder.Register(
                c => c.Resolve<MemoryMappedFile>().CreateViewAccessor())
                .InstancePerLifetimeScope()
                .As<MemoryMappedViewAccessor>();
            builder.Register(
                c => c.Resolve<MemoryMappedViewAccessor>().SafeMemoryMappedViewHandle)
                .InstancePerLifetimeScope()
                .As<SafeBuffer>();

            builder.Register(
                (c, p) =>
                    {
                        var config = c.ResolveConfig<ISemaphoreConfig>();
                        var sharedconifg = c.ResolveConfig<ISharedObjectConfig>();
                        return sharedconifg.Status == SharedObjectStatus.CreateNew
                                   ? SemaphoreHelper.CreateNew(p.Named<int>("initialCount"),
                                                               p.Named<int>("maximumCount"),
                                                               config.GetName())
                                   : Semaphore.OpenExisting(config.GetName());
                    });
            builder.RegisterType<SemaphoreAdaptor>()
                .AsImplementedInterfaces();

            builder.Register((c, p) => EventWaitHandleHelper.CreateNew(false, p.Named<string>("name")))
                .Keyed<EventWaitHandle>(SharedObjectStatus.CreateNew);
            builder.Register((c, p) => EventWaitHandle.OpenExisting(p.Named<string>("name")))
                .Keyed<EventWaitHandle>(SharedObjectStatus.OpenExisting);

            builder.Register(c => Guid.NewGuid())
                .As<Guid>();

            builder.RegisterType<EventWaitHandleAdaptor>()
                .AsImplementedInterfaces();
            builder.RegisterType<SemaphoreFactory>()
                .AsImplementedInterfaces();
            builder.RegisterType<MemoryStatus>()
                .AsImplementedInterfaces();
            builder.RegisterType<SharedIntArray>()
                .AsImplementedInterfaces();
            builder.RegisterType<UnmanagedMemoryAdaptor>()
                .AsImplementedInterfaces();
            builder.RegisterType<SafeBufferAdaptor>()
                .AsImplementedInterfaces();
        }


    }
}